﻿using Microsoft.TeamFoundation.VersionControl.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TFSUtilLibrary.Model;

namespace TFSUtilLibrary
{
    public class History
    {
        /// <summary>
        /// Function to retrieve a list of files checked out at a given time
        /// </summary>
        /// <param name="checkedOutDate"></param>
        /// <returns></returns>
        public static List<CheckOut> GetCheckedOutAt(string uri, DateTime checkedOutDate)
        {
            Connection con = new Connection(uri);
            if (!con.ConnectToTFS())
                Common.Messages.ThrowNonConnect();

            var service = con.VCS;
            QueryHistoryParameters parms = new QueryHistoryParameters("$/*", RecursionType.Full);
            string[] specs = new string[] { @"$/*" };

            parms.IncludeChanges = true;

            var checkouts = new List<CheckOut>();
            QueryCheckouts(checkedOutDate, service, parms, checkouts);
            QueryPendingChanges(checkedOutDate, service, specs, checkouts, uri);

            return checkouts;
        }

        private static void QueryPendingChanges(DateTime checkedOutDate, VersionControlServer service,
            string[] parms, List<CheckOut> checkouts, string uri)
        {
            List<Workspace> wsList = GetWorkspacesWithPendingChanges(uri);

            foreach (Workspace s in wsList)
            {
                var pend = s.GetPendingChanges();
                if (pend.Count() == 0)
                {
                    continue;
                }

                IEnumerable<PendingChange> pendingChanges = pend.Where(p => p.CreationDate <= checkedOutDate);

                foreach (var change in pendingChanges)
                {
                    CheckOut co = new CheckOut()
                    {
                        DateCheckedOut = change.CreationDate,
                        File = change.ServerItem,
                        User = s.OwnerDisplayName
                    };
                    checkouts.Add(co);
                }
            }
        }

        private static List<CheckOut> QueryCheckouts(DateTime checkedOutDate, VersionControlServer service,
            QueryHistoryParameters parms, List<CheckOut> checkouts)
        {
            var changesets = service.QueryHistory(parms);

            foreach (Changeset cs in changesets.Where(c => c.CreationDate <= checkedOutDate))
            {
                foreach (var c in cs.Changes.Where(c => c.Item.CheckinDate >= checkedOutDate))
                {
                    CheckOut co = new CheckOut()
                    {
                        DateCheckedOut = c.Item.CheckinDate,
                        File = c.Item.ArtifactUri.AbsoluteUri,
                        User = cs.Owner
                    };
                    checkouts.Add(co);
                }
            }

            return checkouts;
        }

        private static List<Workspace> GetWorkspacesWithPendingChanges(string uri)
        {
            Connection con = new Connection(uri);
            List<PendingChange[]> changes = new List<PendingChange[]>();

            if (!con.ConnectToTFS())
                Common.Messages.ThrowNonConnect();

            Workspace[] ws = con.VCS.QueryWorkspaces(null, null, null);

            return ws.ToList();
        }

    }
}